package cn.edu.xmu.oomall.order.service;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.order.dao.OrderDao;
import cn.edu.xmu.oomall.order.microservice.ShopFeignService;
import cn.edu.xmu.oomall.order.model.bo.Order;
import cn.edu.xmu.oomall.order.model.bo.Shop;
import cn.edu.xmu.oomall.order.model.vo.NewNormalOrderPostVo;
import cn.edu.xmu.oomall.order.model.vo.OrderSelectRetVo;
import cn.edu.xmu.oomall.order.model.vo.OrderVo;
import cn.edu.xmu.oomall.order.model.po.OrderPo;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.setPoModifiedFields;

@Service
public class OrderService {
    @Autowired
    private OrderDao orderDao;

    @Resource
    ShopFeignService shopFeignService;

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<Order> getOrderByOrderId(Long OrderId) {
        return orderDao.getOrderById(OrderId);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject getOrderStates() {
        return orderDao.getOrderState();
    }

//    @Transactional(rollbackFor = Exception.class)
//    public ReturnObject addOrder(NewNormalOrderPostVo body, Long createBy, String createName) {
//
//    }
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject updateOrder(Long id, OrderVo orderVo, Long loginUser, String loginUserName) {
        Order order = new Order();
        order.setId(id.longValue());
        order.setAddress(orderVo.getAddress());
        setPoModifiedFields(order, loginUser, loginUserName);

        ReturnObject ret;
        ret = orderDao.UpdateOrder(order.getId(), order);
        return ret;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject cancelOrder(Long id, Long loginUser, String loginUserName) {
        Order order = new Order();
        order.setId(id.longValue());
        setPoModifiedFields(order, loginUser, loginUserName);
        order.setState(Order.State.CANCELED.getCode().byteValue());
        var x = getOrderByOrderId(id).getData();
        if (x.getState() != Order.State.COMPLETED.getCode().byteValue()) {
            ReturnObject ret = orderDao.updateOrderState(order);
            return ret;
        }
        else return new ReturnObject(ReturnNo.STATENOTALLOW);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject postfreights(Long id, Long shopId, OrderVo orderVo, Long loginUser, String loginUserName) {
        Order order = new Order();
        order.setId(id.longValue());
        order.setShopId(shopId);
        order.setFreightSn(orderVo.getFreightSn());
        setPoModifiedFields(order, loginUser, loginUserName);
        order.setState(Order.State.PENDING_DELIVERY.getCode().byteValue());
        var x = getOrderByOrderId(id).getData();
        if (!x.getShopId().equals(shopId)) return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);

        if (x.getState() == Order.State.PENDING_DELIVERY.getCode().byteValue()) {
            ReturnObject ret = orderDao.updateOrderState(order);
            return ret;
        }
        else return new ReturnObject(ReturnNo.STATENOTALLOW);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject confirmGroupOrders(Long id, Long shopId, Long loginUser, String loginUserName) {
//        InternalReturnObject<Shop> returnObject;
//        try {
//            returnObject = shopFeignService.getShopById(shopId);
//        }
//        catch (Exception e) {
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
//        }
//        Shop shop = returnObject.getData();

        Order order = new Order();
        order.setId(id.longValue());
        order.setShopId(shopId);
        setPoModifiedFields(order, loginUser, loginUserName);
        order.setState(Order.State.PAYMENT_COMPLETED.getCode().byteValue());
        var x = getOrderByOrderId(id).getData();
        if (!x.getShopId().equals(shopId)) return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        if (x.getState() == Order.State.PENDING_GROUPING.getCode().byteValue()) {
            ReturnObject ret = orderDao.updateOrderState(order);
            return ret;
        }
        else return new ReturnObject(ReturnNo.STATENOTALLOW);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<PageInfo<Object>> shopGetAllSimpleOrders(Long loginUser, Integer page, Integer pageSize) {
        List<OrderPo> orderPos = (List<OrderPo>) orderDao.shopGetAllSimpleOrders(loginUser, page, pageSize).getData();
        List<Object> orderGetAllSimpleOrdersRetVos = new ArrayList<>();
        for (OrderPo po : orderPos)
            orderGetAllSimpleOrdersRetVos.add(po);
        PageInfo<Object> orderRetVoPageInfo = PageInfo.of(orderGetAllSimpleOrdersRetVos);
        OrderSelectRetVo orderSelectRetVo = new OrderSelectRetVo();
        orderSelectRetVo.setPage(page.longValue());
        orderSelectRetVo.setPageSize(pageSize.longValue());
        orderSelectRetVo.setPages((long) orderRetVoPageInfo.getPages());
        orderSelectRetVo.setTotal(orderSelectRetVo.getTotal());
        orderSelectRetVo.setList(orderGetAllSimpleOrdersRetVos);
        return new ReturnObject<>(orderRetVoPageInfo);
    }
}
